/*
 *  This core class represents one instance of SNMP agent.
 *  Agent will always be managed ONLY via AgentManager class
 *  and should not be accessed in any other way.
 *  
 *  Exceptions are thrown back to AgentManager class and 
 *  handled there.
 */

package sk.stuba.fei.ut.snmpmanager;

import java.util.UUID;

import org.json.JSONException;
import org.json.JSONObject;
import org.snmp4j.mp.SnmpConstants;

public class Agent
{
	/*
	 * CONSTANTS
	 */

	private static final String JSON_ID = "id";
	private static final String JSON_TITLE = "title";
	private static final String JSON_CATCHING = "catching";
	private static final String JSON_POLLING = "pooling";
	private static final String JSON_POLLINTERVAL = "interval";
	private static final String JSON_DETAIL = "detail";
	private static final String JSON_IPADDRESS = "address";
	private static final String JSON_PORT = "port";
	private static final String JSON_MAC = "mac";
	private static final String JSON_COMMUNITY = "community";
	private static final String JSON_SNMPVERSION = "version";
	private static final String JSON_WOLPORT = "wolport";

	// default settings for all agents, this can be perhaps configurable on
	// application basis via some intent or preferences class
	private static final boolean AGENT_DEFAULT_TRAPS = false;
	private static final boolean AGENT_DEFAULT_POLL = false;
	private static final String AGENT_DEFAULT_POLLINTERVAL = "120";
	private static final String AGENT_DEFAULT_PORT = "161";
	private static final String AGENT_DEFAULT_COMMUNITY = "public";
	private static final int AGENT_DEFAULT_VERSION = SnmpConstants.version2c;
	private static final String AGENT_DEFAULT_WOLPORT = "9";

	/*
	 * FIELDS
	 */

	// UUID is unique identifier of agent instance, cannot repeat
	private final UUID mID;
	// this is the title as shown to the user, can repeat
	private String mTitle;
	// if set true then we catch traps for this agent
	private boolean mCatchingTraps;
	// if set true then we are polling this Agent
	private boolean mPolled;
	// if polling then we need an interval in seconds
	private String mPollingInterval;
	// this is arbitrary user input, for example something to describe agent
	private String mDetail;
	// this is the value of IPv4 address of the agent as a String
	private String mIpv4Address;
	// this is the port value
	private String mPort;
	// MAC address of agent
	private String mMACAddress;
	// SNMP community value
	private String mCommunity;
	// SNMP version value, see SnmpConstants class
	private int mVersion;
	// WoL port to be used
	private String mWoLport;

	/*
	 * CONSTRUCTORS
	 */

	// Whenever new Agent is created we use this constructor
	public Agent()
	{
		mID = UUID.randomUUID();
		setCatchingTraps( AGENT_DEFAULT_TRAPS );
		setPolled( AGENT_DEFAULT_POLL );
		setPollingInterval( AGENT_DEFAULT_POLLINTERVAL );
		setPort( AGENT_DEFAULT_PORT );
		setCommunity( AGENT_DEFAULT_COMMUNITY );
		setVersion( AGENT_DEFAULT_VERSION );
		setWoLport( AGENT_DEFAULT_WOLPORT );
	}

	// if Agent exists already, get values from memory
	public Agent( JSONObject json ) throws JSONException
	{
		mID = UUID.fromString( json.getString( JSON_ID ) );
		if ( json.has( JSON_TITLE ) )
		{
			setTitle( json.getString( JSON_TITLE ) );
		}
		// if we have value then retrieve, else use default
		if ( json.has( JSON_CATCHING ) )
		{
			setCatchingTraps( json.getBoolean( JSON_CATCHING ) );
		}
		else
		{
			setCatchingTraps( AGENT_DEFAULT_TRAPS );
		}

		if ( json.has( JSON_POLLING ) )
		{
			// if we are polling and have interval set
			if ( json.getBoolean( JSON_POLLING )
					&& json.has( JSON_POLLINTERVAL ) )
			{
				setPolled( true );
				setPollingInterval( json.getString( JSON_POLLINTERVAL ) );
			}
			else
			{ // we can't be polling without interval so set to false
				setPolled( false );
				setPollingInterval( AGENT_DEFAULT_POLLINTERVAL );
			}
		}
		else
		{ // if values not found use defaults;
			setPolled( AGENT_DEFAULT_POLL );
			setPollingInterval( AGENT_DEFAULT_POLLINTERVAL );
		}

		if ( json.has( JSON_DETAIL ) )
		{
			setDetail( json.getString( JSON_DETAIL ) );
		}
		if ( json.has( JSON_IPADDRESS ) )
		{
			setIpv4Address( json.getString( JSON_IPADDRESS ) );
		}
		if ( json.has( JSON_PORT ) )
		{
			setPort( json.getString( JSON_PORT ) );
		}
		else
		{
			setPort( AGENT_DEFAULT_PORT );
		}
		if ( json.has( JSON_MAC ) )
		{
			setMACAddress( json.getString( JSON_MAC ) );
		}
		if ( json.has( JSON_COMMUNITY ) )
		{
			setCommunity( json.getString( JSON_COMMUNITY ) );
		}
		else
		{
			setCommunity( AGENT_DEFAULT_COMMUNITY );
		}
		if ( json.has( JSON_SNMPVERSION ) )
		{
			setVersion( json.getInt( JSON_SNMPVERSION ) );
		}
		else
		{
			setVersion( AGENT_DEFAULT_VERSION );
		}
		if ( json.has( JSON_WOLPORT ) )
		{
			setWoLport( json.getString( JSON_WOLPORT ) );
		}
		else
		{
			setWoLport( AGENT_DEFAULT_WOLPORT );
		}
	}

	/*
	 * GETTERS AND SETTERS
	 */

	public UUID getID()
	{
		return mID;
	}

	public String getTitle()
	{
		return mTitle;
	}

	public void setTitle( String title )
	{
		mTitle = title;
	}

	public boolean isCatchingTraps()
	{
		return mCatchingTraps;
	}

	public void setCatchingTraps( boolean catchingTraps )
	{
		mCatchingTraps = catchingTraps;
	}

	public boolean isPolled()
	{
		return mPolled;
	}

	public void setPolled( boolean polled )
	{
		mPolled = polled;
	}

	public String getPollingInterval()
	{
		return mPollingInterval;
	}

	public void setPollingInterval( String pollingInterval )
	{
		mPollingInterval = pollingInterval;
	}

	public String getDetail()
	{
		return mDetail;
	}

	public void setDetail( String detail )
	{
		mDetail = detail;
	}

	public String getIpv4Address()
	{
		return mIpv4Address;
	}

	public void setIpv4Address( String address )
	{
		mIpv4Address = address;
	}

	public String getPort()
	{
		return mPort;
	}

	public void setPort( String port )
	{
		mPort = port;
	}

	public String getMACAddress()
	{
		return mMACAddress;
	}

	public void setMACAddress( String mACAddress )
	{
		mMACAddress = mACAddress;
	}

	public String getCommunity()
	{
		return mCommunity;
	}

	public void setCommunity( String community )
	{
		mCommunity = community;
	}

	public int getVersion()
	{
		return mVersion;
	}

	public void setVersion( int version )
	{
		mVersion = version;
	}

	public String getWoLport()
	{
		return mWoLport;
	}

	public void setWoLport( String woLport )
	{
		mWoLport = woLport;
	}

	/*
	 * UTILITIES
	 */

	@Override
	public String toString()
	{
		// TODO: how to represent agent in a String?
		return "Agent: " + mTitle + " ( " + mIpv4Address + ":" + mPort + " )";
	}

	// Remember that exceptions are handled in AgentManager class
	public JSONObject toJSON() throws JSONException
	{

		JSONObject json = new JSONObject();
		json.put( JSON_ID, getID().toString() );
		json.put( JSON_TITLE, getTitle() );
		json.put( JSON_CATCHING, isCatchingTraps() );
		json.put( JSON_POLLING, isPolled() );
		json.put( JSON_POLLINTERVAL, getPollingInterval() );
		json.put( JSON_DETAIL, getDetail() );
		json.put( JSON_IPADDRESS, getIpv4Address() );
		json.put( JSON_PORT, getPort() );
		json.put( JSON_MAC, getMACAddress() );
		json.put( JSON_COMMUNITY, getCommunity() );
		json.put( JSON_SNMPVERSION, getVersion() );
		json.put( JSON_WOLPORT, getWoLport() );
		return json;
	}
}
